package org.cjlm.ui.db;

import org.cjlm.config.ConfigLoader;
import org.cjlm.config.DbtypeConfig;
import org.cjlm.ui.pub.MInternalFrame;

import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.table.AbstractTableModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.sql.DriverManager;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors; 
 
public class DBConnectorFrame extends MInternalFrame {
    private final DataSourceTableModel tableModel = new DataSourceTableModel();
    private final JTable dataSourceTable = new JTable(tableModel);
    private final JTextField searchField = new JTextField(20);
    private final JButton newBtn = new JButton("新增");
    private final JButton saveBtn = new JButton("保存");
    private final JButton testBtn = new JButton("测试连接");
    private final JButton deleteBtn = new JButton("删除");
    private final JButton setDefaultBtn = new JButton("设为默认");
    
    // 详情区域组件 
    private final JTextField nameField = new JTextField();
    private final JComboBox<String> typeCombo = new JComboBox<>();
    private final JTextField urlField = new JTextField("jdbc:mysql://localhost:3306");
    private final JTextField userField = new JTextField();
    private final JPasswordField passField = new JPasswordField();
    private final JCheckBox defaultCheck = new JCheckBox("设为默认数据源");

    private List<DbtypeConfig> dbtypeConfigs; // 存储从Database.json 加载的配置
    private String currentId; // 当前编辑的数据源ID
 
    public DBConnectorFrame(String title, boolean max, int width, int height) {
        super(title, max, width, height);
        initDbtypeConfigs(); // 加载数据库类型配置
        initUI();
        loadDataSources();
    }
 
    @Override 
    public String getDefaultTile() {
        return "数据源管理";
    }

    /**
     * 加载Database.json 中的数据库类型配置
     */
    private void initDbtypeConfigs() {

        try {
            dbtypeConfigs = ConfigLoader.loadDbtypeConfig("Dbtype");
            // 初始化类型下拉框
            for (DbtypeConfig config : dbtypeConfigs) {
                typeCombo.addItem(config.getType());
            }
        }catch (Exception e){
            showErrorDialog("配置错误", "加载数据库配置失败", e);
        }
    }
 
    private void initUI() {
        setLayout(new BorderLayout(10, 10));
        setBorder(new EmptyBorder(10, 10, 10, 10));
 
        // 顶部搜索和操作区 
        JPanel topPanel = createTopPanel();
        add(topPanel, BorderLayout.NORTH);
 
        // 中心分割面板 
        JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
        splitPane.setResizeWeight(0.3);
        splitPane.setLeftComponent(createListPanel()); 
        splitPane.setRightComponent(createDetailPanel());
        // 添加分割条监听器，防止列表面板消失
        splitPane.addPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY,
                evt -> splitPane.setDividerLocation(0.3));
        add(splitPane, BorderLayout.CENTER);
    }
 
    private JPanel createTopPanel() {
        JPanel panel = new JPanel(new BorderLayout(10, 10));
        
        // 搜索区域 
        JPanel searchPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        searchPanel.add(new  JLabel("搜索:"));
        searchPanel.add(searchField); 
        
        // 操作按钮 
        JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
        buttonPanel.add(newBtn); 
        
        panel.add(searchPanel,  BorderLayout.WEST);
        panel.add(buttonPanel,  BorderLayout.EAST);
        
        // 搜索监听 
        searchField.getDocument().addDocumentListener(new  DocumentListener() {
            public void changedUpdate(DocumentEvent e) { filter(); }
            public void insertUpdate(DocumentEvent e) { filter(); }
            public void removeUpdate(DocumentEvent e) { filter(); }
        });
        
        // 按钮事件 
        newBtn.addActionListener(e  -> createNewDataSource());
        
        return panel;
    }
 
    private JScrollPane createListPanel() {
        dataSourceTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 
        dataSourceTable.getSelectionModel().addListSelectionListener(this::handleSelectionChange); 
        dataSourceTable.setRowHeight(30); 
        
        JScrollPane scrollPane = new JScrollPane(dataSourceTable);
        scrollPane.setBorder(BorderFactory.createTitledBorder(" 数据源列表"));
        scrollPane.setMinimumSize(new  Dimension(200, 300));
        return scrollPane;
    }
 
    private JPanel createDetailPanel() {
        JPanel panel = new JPanel(new BorderLayout(10, 10));
        panel.setBorder(BorderFactory.createTitledBorder(" 数据源详情"));
        
        // 表单区域
        // 替换为GridBagLayout实现固定布局
        JPanel formPanel = new JPanel(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.insets  = new Insets(5, 5, 5, 5);
        gbc.anchor  = GridBagConstraints.WEST;
        gbc.fill  = GridBagConstraints.HORIZONTAL;

        // 名称字段
        gbc.gridx  = 0; gbc.gridy  = 0;
        formPanel.add(new  JLabel("名称*:"), gbc);
        gbc.gridx  = 1; gbc.weightx  = 1.0;
        formPanel.add(nameField,  gbc);
        gbc.weightx  = 0;

        // 类型下拉框
        gbc.gridy  = 1; gbc.gridx  = 0;
        formPanel.add(new  JLabel("类型:"), gbc);
        gbc.gridx  = 1;
        formPanel.add(typeCombo,  gbc);

        // URL字段
        gbc.gridy  = 2; gbc.gridx  = 0;
        formPanel.add(new  JLabel("连接URL*:"), gbc);
        gbc.gridx  = 1;
        formPanel.add(urlField,  gbc);

        // 用户名字段
        gbc.gridy  = 3; gbc.gridx  = 0;
        formPanel.add(new  JLabel("用户名:"), gbc);
        gbc.gridx  = 1;
        formPanel.add(userField,  gbc);

        // 密码字段
        gbc.gridy  = 4; gbc.gridx  = 0;
        formPanel.add(new  JLabel("密码:"), gbc);
        gbc.gridx  = 1;
        formPanel.add(passField,  gbc);

        // 设置固定高度组件
        Dimension fixedSize = new Dimension(300, 28);
        urlField.setPreferredSize(fixedSize);
        nameField.setPreferredSize(fixedSize);
        userField.setPreferredSize(fixedSize);
        passField.setPreferredSize(fixedSize);
        typeCombo.setPreferredSize(fixedSize);

        // 底部操作区 
        JPanel actionPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
        actionPanel.add(defaultCheck); 
        actionPanel.add(testBtn); 
        actionPanel.add(saveBtn); 
        actionPanel.add(deleteBtn); 
        actionPanel.add(setDefaultBtn); 
        
        panel.add(formPanel,  BorderLayout.CENTER);
        panel.add(actionPanel,  BorderLayout.SOUTH);

        // 事件监听
        setupEventListeners();

        return panel;
    }

    private void setupEventListeners() {
        // 类型选择事件：自动填充URL模板
        typeCombo.addActionListener(e  -> {
            String selectedType = (String) typeCombo.getSelectedItem();
            if (selectedType != null) {
                for (DbtypeConfig config : dbtypeConfigs) {
                    if (config.getType().equals(selectedType))  {
                        urlField.setText(config.getUrlTemplate());
                        break;
                    }
                }
            }
        });

        // 按钮事件
        saveBtn.addActionListener(this::saveDataSource);
        testBtn.addActionListener(this::testConnection);
        deleteBtn.addActionListener(this::deleteDataSource);
        setDefaultBtn.addActionListener(this::setDefaultDataSource);
    }

    private void loadDataSources() {
        tableModel.setDataSources(DataSourceManager.getAllDataSources());
    }
 
    private void filter() {
        String keyword = searchField.getText().toLowerCase(); 
        List<DataSourceConfig> filtered = DataSourceManager.getAllDataSources().stream() 
                .filter(ds -> ds.getName().toLowerCase().contains(keyword)) 
                .collect(Collectors.toList()); 
        tableModel.setDataSources(filtered); 
    }
 
    private void createNewDataSource() {
        currentId = null;
        nameField.setText(""); 
        typeCombo.setSelectedIndex(0); 
        urlField.setText("jdbc:mysql://localhost:3306"); 
        userField.setText(""); 
        passField.setText(""); 
        defaultCheck.setSelected(false); 
        dataSourceTable.clearSelection(); 
    }
 
    private void handleSelectionChange(ListSelectionEvent e) {
        if (e.getValueIsAdjusting())  return;
        
        int row = dataSourceTable.getSelectedRow(); 
        if (row >= 0) {
            DataSourceConfig config = tableModel.getDataSourceAt(row); 
            currentId = config.getId(); 
            nameField.setText(config.getName()); 
            typeCombo.setSelectedItem(config.getType()); 
            urlField.setText(config.getUrl()); 
            userField.setText(config.getUsername()); 
            passField.setText(config.getPassword()); 
            defaultCheck.setSelected(config.isDefault()); 
        }
    }
 
    private void saveDataSource(ActionEvent e) {
        if (nameField.getText().isEmpty()  || urlField.getText().isEmpty())  {
            showErrorDialog("错误", "名称和URL不能为空");
            return;
        }
        
        DataSourceConfig config = new DataSourceConfig();
        config.setId(currentId  != null ? currentId : UUID.randomUUID().toString()); 
        config.setName(nameField.getText()); 
        config.setType((String)  typeCombo.getSelectedItem()); 
        config.setUrl(urlField.getText()); 
        config.setUsername(userField.getText()); 
        config.setPassword(new  String(passField.getPassword())); 
        config.setDefault(defaultCheck.isSelected()); 
        
        if (currentId == null) {
            DataSourceManager.addDataSource(config); 
        } else {
            DataSourceManager.updateDataSource(config); 
        }
        
        loadDataSources();
        showHintDialog("成功","保存成功");
    }
 
    private void testConnection(ActionEvent e) {
        String selectedType = (String) typeCombo.getSelectedItem();
        if (selectedType == null) {
            showErrorDialog("错误", "请先选择数据库类型");
            return;
        }

        // 查找驱动类
        String driverClass = null;
        for (DbtypeConfig config : dbtypeConfigs) {
            if (config.getType().equals(selectedType))  {
                driverClass = config.getDriver();
                break;
            }
        }

        if (driverClass == null) {
            showErrorDialog("配置错误", "未找到" + selectedType + "的驱动配置");
            return;
        }

        try {
            // 加载驱动
            Class.forName(driverClass);

            // 获取连接参数
            String url = urlField.getText();
            String user = userField.getText();
            char[] password = passField.getPassword();

            // 测试连接
            DriverManager.getConnection(url,  user, new String(password));
            showHintDialog("测试结果", "连接成功！");
        } catch (ClassNotFoundException ex) {
            showErrorDialog("驱动错误", "驱动类加载失败", ex);
        } catch (Exception ex) {
            showErrorDialog("连接错误", "连接失败", ex);
        }
    }
 
    private void deleteDataSource(ActionEvent e) {
        if (currentId == null) return;

        if (showYesNoDialog("确认删除", "确定删除此数据源？") == JOptionPane.YES_OPTION) {
            DataSourceManager.deleteDataSource(currentId); 
            createNewDataSource();
            loadDataSources();
        }
    }
 
    private void setDefaultDataSource(ActionEvent e) {
        if (currentId != null) {
            DataSourceManager.setDefaultDataSource(currentId); 
            loadDataSources();
        }
    }
 
    // 自定义表格模型 
    private static class DataSourceTableModel extends AbstractTableModel {
        private final String[] COLUMNS = {"名称", "类型", "默认"};
        private List<DataSourceConfig> dataSources = new ArrayList<>();
 
        public void setDataSources(List<DataSourceConfig> dataSources) {
            this.dataSources  = dataSources;
            fireTableDataChanged();
        }
 
        public DataSourceConfig getDataSourceAt(int row) {
            return dataSources.get(row); 
        }
 
        @Override 
        public int getRowCount() {
            return dataSources.size(); 
        }
 
        @Override 
        public int getColumnCount() {
            return COLUMNS.length; 
        }
 
        @Override 
        public String getColumnName(int column) {
            return COLUMNS[column];
        }
 
        @Override 
        public Object getValueAt(int row, int col) {
            DataSourceConfig config = dataSources.get(row); 
            switch (col) {
                case 0: return config.getName(); 
                case 1: return config.getType(); 
                case 2: return config.isDefault()  ? "✓" : "";
                default: return "";
            }
        }
    }
}